package com.xmb.wcapi.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xmb.wcapi.constant.DepConstant;
import com.xmb.wcapi.entity.BaseMaterial;
import com.xmb.wcapi.entity.CustomQualityData;
import com.xmb.wcapi.exception.InterfaceErrorException;
import com.xmb.wcapi.mapper.BaseMaterialMapper;
import com.xmb.wcapi.mapper.CustomQualityDataMapper;
import com.xmb.wcapi.service.ICustomQualityDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 自定义生产工单数据表 服务实现类
 * </p>
 *
 * @author huangping
 * @since 2024-07-25
 */
@Service
public class CustomQualityDataServiceImpl extends ServiceImpl<CustomQualityDataMapper, CustomQualityData> implements ICustomQualityDataService {

    @Autowired
    private BaseMaterialMapper baseMaterialMapper;


    public List<CustomQualityData> qualityDataList(String startTime,String endTime){
        List<CustomQualityData> list = list(Wrappers.lambdaQuery(CustomQualityData.class).between(CustomQualityData::getTimes, startTime, endTime));
        for (CustomQualityData record : list) {
            //计算待处理
            BigDecimal invest = record.getInvest();
            invest = invest.subtract(record.getNonDefective()).subtract(record.getDefectiveProducts());
            record.setPending(invest);
            record.setPendingCumulative(invest);
            if (invest.intValue() < 1){
                record.setPending(BigDecimal.valueOf(0));
                record.setPendingCumulative(BigDecimal.valueOf(0));
            }
            //制程替换
            if (StringUtils.isNotEmpty(record.getStrGoodsName())){
                for (DepConstant value : DepConstant.values()) {
                    if (record.getStrGoodsName().contains(value.getCode())){
                        record.setStrDepartmentName(value.getMessage());
                    }
                }
            }
        }
        return list;
    }

    @Override
    public List<CustomQualityData> qualityDataList(String startTime, String endTime, String material) {
        List<CustomQualityData> list = list(Wrappers.lambdaQuery(CustomQualityData.class)
                .between(CustomQualityData::getTimes, startTime, endTime)
                .gt(CustomQualityData::getTimes,startTime)
                .le(CustomQualityData::getTimes,endTime)
                .eq(CustomQualityData::getMaterial, material));
        for (CustomQualityData record : list) {
            //计算待处理
            BigDecimal invest = record.getInvest();
            invest = invest.subtract(record.getNonDefective()).subtract(record.getDefectiveProducts());
            record.setPending(invest);
            record.setPendingCumulative(invest);
            if (invest.intValue() < 1){
                record.setPending(BigDecimal.valueOf(0));
                record.setPendingCumulative(BigDecimal.valueOf(0));
            }
            //制程替换
            if (StringUtils.isNotEmpty(record.getStrGoodsName())){
                for (DepConstant value : DepConstant.values()) {
                    if (record.getStrGoodsName().contains(value.getCode())){
                        record.setStrDepartmentName(value.getMessage());
                    }
                }
            }
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadCustomQuality(List<CustomQualityData> list) {
        //校验导入的料号是否存在
        Set<String> collect = list.stream().map(CustomQualityData::getMaterial).collect(Collectors.toSet());
        List<BaseMaterial> baseMaterials = baseMaterialMapper.selectList(Wrappers.lambdaQuery(BaseMaterial.class)
                        .eq(BaseMaterial::isChecked,true)
                .in(BaseMaterial::getDjMaterial, collect));
        if (collect.size() <= baseMaterials.size()){
            throw new InterfaceErrorException("导入的料号在库存不存在!");
        }
        //校验是否存在相同工单号
        Set<Integer> collect1 = list.stream().map(CustomQualityData::getLngWorkLoadNo).collect(Collectors.toSet());
        if (collect1.size() <= baseMaterials.size()){
            throw new InterfaceErrorException("存在重复工单号!");
        }
        //校验工单日期是否小于今天
        String format = DateUtil.format(new Date(), "yyy-MM-dd");
        for (CustomQualityData data : list) {
            if (StringUtils.isEmpty(data.getMaterial())){
                throw new InterfaceErrorException("料号不能为空！");
            }
            if (StringUtils.isEmpty(data.getTimes())){
                throw new InterfaceErrorException("工单日期不能为空！");
            }else {
                String format1 = DateUtil.format(DateUtil.parseDate(data.getTimes()), "yyy-MM-dd");
                if (format1.compareTo(format) < 0){
                    throw new InterfaceErrorException("工单日期不能小于今天，昨天已经结转，不能添加昨天日期！");
                }
            }
            if (null == data.getNonDefective()){
                throw new InterfaceErrorException("良品数不能为空！");
            }
            if (null == data.getDefectiveProducts()){
                throw new InterfaceErrorException("不良品数不能为空！");
            }
        }
        //去重复，存在公用bom
        baseMaterials = baseMaterials.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(BaseMaterial::getDjMaterial))), ArrayList::new)
        );
        Map<String, BaseMaterial> collect2 = baseMaterials.stream().collect(Collectors.toMap(BaseMaterial::getDjMaterial, item -> item));
        //填充工单数据，新增
        for (CustomQualityData data : list) {
            BaseMaterial baseMaterial = collect2.get(data.getMaterial());
            CustomQualityData cus = new CustomQualityData();
            cus.setTimes(data.getTimes());
            cus.setLngWorkLoadNo(data.getLngWorkLoadNo());
            cus.setStrDepartmentName(baseMaterial.getClassName());
            cus.setStrGoodsName(baseMaterial.getMaterialMrk());
            cus.setMaterial(data.getMaterial());
            cus.setCusMaterial(baseMaterial.getCusMaterial());
            cus.setTypeOfMachine(baseMaterial.getTypeOfMachine());
            cus.setInvest(data.getInvest());
            cus.setPlanSum(data.getPlanSum());
            cus.setNonDefective(data.getNonDefective());
            cus.setDefectiveProducts(data.getDefectiveProducts());
            cus.setPoorDistribution(data.getPoorDistribution());
            saveOrUpdate(cus);
        }
    }
}
